home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 May / maximum-cd-2009-05.iso / DiscContents / Firefox Setup 3.0.6.exe / nonlocalized / components / nsBrowserContentHandler.js < prev    next >
Encoding:
JavaScript  |  2009-01-19  |  32.3 KB  |  924 lines

  1. //@line 37 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  2.  
  3. const nsISupports            = Components.interfaces.nsISupports;
  4.  
  5. const nsIBrowserDOMWindow    = Components.interfaces.nsIBrowserDOMWindow;
  6. const nsIBrowserHandler      = Components.interfaces.nsIBrowserHandler;
  7. const nsIBrowserHistory      = Components.interfaces.nsIBrowserHistory;
  8. const nsIChannel             = Components.interfaces.nsIChannel;
  9. const nsICommandLine         = Components.interfaces.nsICommandLine;
  10. const nsICommandLineHandler  = Components.interfaces.nsICommandLineHandler;
  11. const nsIContentHandler      = Components.interfaces.nsIContentHandler;
  12. const nsIDocShellTreeItem    = Components.interfaces.nsIDocShellTreeItem;
  13. const nsIDOMChromeWindow     = Components.interfaces.nsIDOMChromeWindow;
  14. const nsIDOMWindow           = Components.interfaces.nsIDOMWindow;
  15. const nsIFactory             = Components.interfaces.nsIFactory;
  16. const nsIFileURL             = Components.interfaces.nsIFileURL;
  17. const nsIHttpProtocolHandler = Components.interfaces.nsIHttpProtocolHandler;
  18. const nsIInterfaceRequestor  = Components.interfaces.nsIInterfaceRequestor;
  19. const nsINetUtil             = Components.interfaces.nsINetUtil;
  20. const nsIPrefBranch          = Components.interfaces.nsIPrefBranch;
  21. const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString;
  22. const nsISupportsString      = Components.interfaces.nsISupportsString;
  23. const nsIURIFixup            = Components.interfaces.nsIURIFixup;
  24. const nsIWebNavigation       = Components.interfaces.nsIWebNavigation;
  25. const nsIWindowMediator      = Components.interfaces.nsIWindowMediator;
  26. const nsIWindowWatcher       = Components.interfaces.nsIWindowWatcher;
  27. const nsICategoryManager     = Components.interfaces.nsICategoryManager;
  28. const nsIWebNavigationInfo   = Components.interfaces.nsIWebNavigationInfo;
  29. const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
  30. const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
  31.  
  32. const NS_BINDING_ABORTED = 0x804b0002;
  33. const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
  34. const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
  35.  
  36. const URI_INHERITS_SECURITY_CONTEXT = nsIHttpProtocolHandler
  37.                                         .URI_INHERITS_SECURITY_CONTEXT;
  38.  
  39. function shouldLoadURI(aURI) {
  40.   if (aURI && !aURI.schemeIs("chrome"))
  41.     return true;
  42.  
  43.   dump("*** Preventing external load of chrome: URI into browser window\n");
  44.   dump("    Use -chrome <uri> instead\n");
  45.   return false;
  46. }
  47.  
  48. function resolveURIInternal(aCmdLine, aArgument) {
  49.   var uri = aCmdLine.resolveURI(aArgument);
  50.  
  51.   if (!(uri instanceof nsIFileURL)) {
  52.     return uri;
  53.   }
  54.  
  55.   try {
  56.     if (uri.file.exists())
  57.       return uri;
  58.   }
  59.   catch (e) {
  60.     Components.utils.reportError(e);
  61.   }
  62.  
  63.   // We have interpreted the argument as a relative file URI, but the file
  64.   // doesn't exist. Try URI fixup heuristics: see bug 290782.
  65.  
  66.   try {
  67.     var urifixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
  68.                              .getService(nsIURIFixup);
  69.  
  70.     uri = urifixup.createFixupURI(aArgument, 0);
  71.   }
  72.   catch (e) {
  73.     Components.utils.reportError(e);
  74.   }
  75.  
  76.   return uri;
  77. }
  78.  
  79. const OVERRIDE_NONE        = 0;
  80. const OVERRIDE_NEW_PROFILE = 1;
  81. const OVERRIDE_NEW_MSTONE  = 2;
  82. /**
  83.  * Determines whether a home page override is needed.
  84.  * Returns:
  85.  *  OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
  86.  *  OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
  87.  *                      Gecko milestone (i.e. right after an upgrade).
  88.  *  OVERRIDE_NONE otherwise.
  89.  */
  90. function needHomepageOverride(prefb) {
  91.   var savedmstone = null;
  92.   try {
  93.     savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone");
  94.   } catch (e) {}
  95.  
  96.   if (savedmstone == "ignore")
  97.     return OVERRIDE_NONE;
  98.  
  99.   var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
  100.                          .getService(nsIHttpProtocolHandler).misc;
  101.  
  102.   if (mstone != savedmstone) {
  103.     // Bug 462254. Previous releases had a default pref to suppress the EULA
  104.     // agreement if the platform's installer had already shown one. Now with
  105.     // about:rights we've removed the EULA stuff and default pref, but we need
  106.     // a way to make existing profiles retain the default that we removed.
  107.     if (savedmstone)
  108.       prefb.setBoolPref("browser.rights.3.shown", true);
  109.     
  110.     prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
  111.     return (savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE);
  112.   }
  113.  
  114.   return OVERRIDE_NONE;
  115. }
  116.  
  117. // Copies a pref override file into the user's profile pref-override folder,
  118. // and then tells the pref service to reload it's default prefs.
  119. function copyPrefOverride() {
  120.   try {
  121.     var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
  122.                                 .getService(Components.interfaces.nsIProperties);
  123.     const NS_APP_EXISTING_PREF_OVERRIDE = "ExistingPrefOverride";
  124.     var prefOverride = fileLocator.get(NS_APP_EXISTING_PREF_OVERRIDE,
  125.                                        Components.interfaces.nsIFile);
  126.     if (!prefOverride.exists())
  127.       return; // nothing to do
  128.  
  129.     const NS_APP_PREFS_OVERRIDE_DIR     = "PrefDOverride";
  130.     var prefOverridesDir = fileLocator.get(NS_APP_PREFS_OVERRIDE_DIR,
  131.                                            Components.interfaces.nsIFile);
  132.  
  133.     // Check for any existing pref overrides, and remove them if present
  134.     var existingPrefOverridesFile = prefOverridesDir.clone();
  135.     existingPrefOverridesFile.append(prefOverride.leafName);
  136.     if (existingPrefOverridesFile.exists())
  137.       existingPrefOverridesFile.remove(false);
  138.  
  139.     prefOverride.copyTo(prefOverridesDir, null);
  140.  
  141.     // Now that we've installed the new-profile pref override file,
  142.     // re-read the default prefs.
  143.     var prefSvcObs = Components.classes["@mozilla.org/preferences-service;1"]
  144.                                .getService(Components.interfaces.nsIObserver);
  145.     prefSvcObs.observe(null, "reload-default-prefs", null);
  146.   } catch (ex) {
  147.     Components.utils.reportError(ex);
  148.   }
  149. }
  150.  
  151. // Flag used to indicate that the arguments to openWindow can be passed directly.
  152. const NO_EXTERNAL_URIS = 1;
  153.  
  154. function openWindow(parent, url, target, features, args, noExternalArgs) {
  155.   var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  156.                          .getService(nsIWindowWatcher);
  157.  
  158.   if (noExternalArgs == NO_EXTERNAL_URIS) {
  159.     // Just pass in the defaultArgs directly
  160.     var argstring;
  161.     if (args) {
  162.       argstring = Components.classes["@mozilla.org/supports-string;1"]
  163.                             .createInstance(nsISupportsString);
  164.       argstring.data = args;
  165.     }
  166.  
  167.     return wwatch.openWindow(parent, url, target, features, argstring);
  168.   }
  169.   
  170.   // Pass an array to avoid the browser "|"-splitting behavior.
  171.   var argArray = Components.classes["@mozilla.org/supports-array;1"]
  172.                     .createInstance(Components.interfaces.nsISupportsArray);
  173.  
  174.   // add args to the arguments array
  175.   var stringArgs = null;
  176.   if (args instanceof Array) // array
  177.     stringArgs = args;
  178.   else if (args) // string
  179.     stringArgs = [args];
  180.  
  181.   if (stringArgs) {
  182.     // put the URIs into argArray
  183.     var uriArray = Components.classes["@mozilla.org/supports-array;1"]
  184.                        .createInstance(Components.interfaces.nsISupportsArray);
  185.     stringArgs.forEach(function (uri) {
  186.       var sstring = Components.classes["@mozilla.org/supports-string;1"]
  187.                               .createInstance(nsISupportsString);
  188.       sstring.data = uri;
  189.       uriArray.AppendElement(sstring);
  190.     });
  191.     argArray.AppendElement(uriArray);
  192.   } else {
  193.     argArray.AppendElement(null);
  194.   }
  195.  
  196.   // Pass these as null to ensure that we always trigger the "single URL"
  197.   // behavior in browser.js's BrowserStartup (which handles the window
  198.   // arguments)
  199.   argArray.AppendElement(null); // charset
  200.   argArray.AppendElement(null); // referer
  201.   argArray.AppendElement(null); // postData
  202.   argArray.AppendElement(null); // allowThirdPartyFixup
  203.  
  204.   return wwatch.openWindow(parent, url, target, features, argArray);
  205. }
  206.  
  207. function openPreferences() {
  208.   var features = "chrome,titlebar,toolbar,centerscreen,dialog=no";
  209.   var url = "chrome://browser/content/preferences/preferences.xul";
  210.  
  211.   var win = getMostRecentWindow("Browser:Preferences");
  212.   if (win) {
  213.     win.focus();
  214.   } else {
  215.     openWindow(null, url, "_blank", features);
  216.   }
  217. }
  218.  
  219. function getMostRecentWindow(aType) {
  220.   var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  221.                      .getService(nsIWindowMediator);
  222.   return wm.getMostRecentWindow(aType);
  223. }
  224.  
  225. //@line 268 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  226.  
  227. // this returns the most recent non-popup browser window
  228. function getMostRecentBrowserWindow() {
  229.   var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
  230.                      .getService(Components.interfaces.nsIWindowMediator);
  231.  
  232. //@line 288 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  233.   var windowList = wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
  234.   if (!windowList.hasMoreElements())
  235.     return null;
  236.  
  237.   var win = windowList.getNext();
  238.   while (win.document.documentElement.getAttribute("chromehidden")) {
  239.     if (!windowList.hasMoreElements()) 
  240.       return null;
  241.  
  242.     win = windowList.getNext();
  243.   }
  244. //@line 300 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  245.  
  246.   return win;
  247. }
  248.  
  249. function doSearch(searchTerm, cmdLine) {
  250.   var ss = Components.classes["@mozilla.org/browser/search-service;1"]
  251.                      .getService(nsIBrowserSearchService);
  252.  
  253.   var submission = ss.defaultEngine.getSubmission(searchTerm, null);
  254.  
  255.   // fill our nsISupportsArray with uri-as-wstring, null, null, postData
  256.   var sa = Components.classes["@mozilla.org/supports-array;1"]
  257.                      .createInstance(Components.interfaces.nsISupportsArray);
  258.  
  259.   var wuri = Components.classes["@mozilla.org/supports-string;1"]
  260.                        .createInstance(Components.interfaces.nsISupportsString);
  261.   wuri.data = submission.uri.spec;
  262.  
  263.   sa.AppendElement(wuri);
  264.   sa.AppendElement(null);
  265.   sa.AppendElement(null);
  266.   sa.AppendElement(submission.postData);
  267.  
  268.   // XXXbsmedberg: use handURIToExistingBrowser to obey tabbed-browsing
  269.   // preferences, but need nsIBrowserDOMWindow extensions
  270.  
  271.   var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
  272.                          .getService(nsIWindowWatcher);
  273.  
  274.   return wwatch.openWindow(null, nsBrowserContentHandler.chromeURL,
  275.                            "_blank",
  276.                            "chrome,dialog=no,all" +
  277.                              nsBrowserContentHandler.getFeatures(cmdLine),
  278.                            sa);
  279. }
  280.  
  281. var nsBrowserContentHandler = {
  282.   /* helper functions */
  283.  
  284.   mChromeURL : null,
  285.  
  286.   get chromeURL() {
  287.     if (this.mChromeURL) {
  288.       return this.mChromeURL;
  289.     }
  290.  
  291.     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
  292.                           .getService(nsIPrefBranch);
  293.     this.mChromeURL = prefb.getCharPref("browser.chromeURL");
  294.  
  295.     return this.mChromeURL;
  296.   },
  297.  
  298.   /* nsISupports */
  299.   QueryInterface : function bch_QI(iid) {
  300.     if (!iid.equals(nsISupports) &&
  301.         !iid.equals(nsICommandLineHandler) &&
  302.         !iid.equals(nsIBrowserHandler) &&
  303.         !iid.equals(nsIContentHandler) &&
  304.         !iid.equals(nsICommandLineValidator) &&
  305.         !iid.equals(nsIFactory))
  306.       throw Components.results.NS_ERROR_NO_INTERFACE;
  307.  
  308.     return this;
  309.   },
  310.  
  311.   /* nsICommandLineHandler */
  312.   handle : function bch_handle(cmdLine) {
  313.     if (cmdLine.handleFlag("browser", false)) {
  314.       // Passing defaultArgs, so use NO_EXTERNAL_URIS
  315.       openWindow(null, this.chromeURL, "_blank",
  316.                  "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  317.                  this.defaultArgs, NO_EXTERNAL_URIS);
  318.       cmdLine.preventDefault = true;
  319.     }
  320.  
  321.     try {
  322.       var remoteCommand = cmdLine.handleFlagWithParam("remote", true);
  323.     }
  324.     catch (e) {
  325.       throw NS_ERROR_ABORT;
  326.     }
  327.  
  328.     if (remoteCommand != null) {
  329.       try {
  330.         var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand);
  331.         var remoteVerb;
  332.         if (a) {
  333.           remoteVerb = a[1].toLowerCase();
  334.           var remoteParams = [];
  335.           var sepIndex = a[2].lastIndexOf(",");
  336.           if (sepIndex == -1)
  337.             remoteParams[0] = a[2];
  338.           else {
  339.             remoteParams[0] = a[2].substring(0, sepIndex);
  340.             remoteParams[1] = a[2].substring(sepIndex + 1);
  341.           }
  342.         }
  343.  
  344.         switch (remoteVerb) {
  345.         case "openurl":
  346.         case "openfile":
  347.           // openURL(<url>)
  348.           // openURL(<url>,new-window)
  349.           // openURL(<url>,new-tab)
  350.  
  351.           // First param is the URL, second param (if present) is the "target"
  352.           // (tab, window)
  353.           var url = remoteParams[0];
  354.           var target = nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW;
  355.           if (remoteParams[1]) {
  356.             var targetParam = remoteParams[1].toLowerCase()
  357.                                              .replace(/^\s*|\s*$/g, "");
  358.             if (targetParam == "new-tab")
  359.               target = nsIBrowserDOMWindow.OPEN_NEWTAB;
  360.             else if (targetParam == "new-window")
  361.               target = nsIBrowserDOMWindow.OPEN_NEWWINDOW;
  362.             else {
  363.               // The "target" param isn't one of our supported values, so
  364.               // assume it's part of a URL that contains commas.
  365.               url += "," + remoteParams[1];
  366.             }
  367.           }
  368.  
  369.           var uri = resolveURIInternal(cmdLine, url);
  370.           handURIToExistingBrowser(uri, target, cmdLine);
  371.           break;
  372.  
  373.         case "xfedocommand":
  374.           // xfeDoCommand(openBrowser)
  375.           if (remoteParams[0].toLowerCase() != "openbrowser")
  376.             throw NS_ERROR_ABORT;
  377.  
  378.           // Passing defaultArgs, so use NO_EXTERNAL_URIS
  379.           openWindow(null, this.chromeURL, "_blank",
  380.                      "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  381.                      this.defaultArgs, NO_EXTERNAL_URIS);
  382.           break;
  383.  
  384.         default:
  385.           // Somebody sent us a remote command we don't know how to process:
  386.           // just abort.
  387.           throw "Unknown remote command.";
  388.         }
  389.  
  390.         cmdLine.preventDefault = true;
  391.       }
  392.       catch (e) {
  393.         Components.utils.reportError(e);
  394.         // If we had a -remote flag but failed to process it, throw
  395.         // NS_ERROR_ABORT so that the xremote code knows to return a failure
  396.         // back to the handling code.
  397.         throw NS_ERROR_ABORT;
  398.       }
  399.     }
  400.  
  401.     var uriparam;
  402.     try {
  403.       while ((uriparam = cmdLine.handleFlagWithParam("new-window", false))) {
  404.         var uri = resolveURIInternal(cmdLine, uriparam);
  405.         if (!shouldLoadURI(uri))
  406.           continue;
  407.         openWindow(null, this.chromeURL, "_blank",
  408.                    "chrome,dialog=no,all" + this.getFeatures(cmdLine),
  409.                    uri.spec);
  410.         cmdLine.preventDefault = true;
  411.       }
  412.     }
  413.     catch (e) {
  414.       Components.utils.reportError(e);
  415.     }
  416.  
  417.     try {
  418.       while ((uriparam = cmdLine.handleFlagWithParam("new-tab", false))) {
  419.         var uri = resolveURIInternal(cmdLine, uriparam);
  420.         handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine);
  421.         cmdLine.preventDefault = true;
  422.       }
  423.     }
  424.     catch (e) {
  425.       Components.utils.reportError(e);
  426.     }
  427.  
  428.     var chromeParam = cmdLine.handleFlagWithParam("chrome", false);
  429.     if (chromeParam) {
  430.  
  431.       // Handle the old preference dialog URL separately (bug 285416)
  432.       if (chromeParam == "chrome://browser/content/pref/pref.xul") {
  433.         openPreferences();
  434.         cmdLine.preventDefault = true;
  435.       } else try {
  436.         // only load URIs which do not inherit chrome privs
  437.         var features = "chrome,dialog=no,all" + this.getFeatures(cmdLine);
  438.         var uri = resolveURIInternal(cmdLine, chromeParam);
  439.         var netutil = Components.classes["@mozilla.org/network/util;1"]
  440.                                 .getService(nsINetUtil);
  441.         if (!netutil.URIChainHasFlags(uri, URI_INHERITS_SECURITY_CONTEXT)) {
  442.           openWindow(null, uri.spec, "_blank", features);
  443.           cmdLine.preventDefault = true;
  444.         }
  445.       }
  446.       catch (e) {
  447.         Components.utils.reportError(e);
  448.       }
  449.     }
  450.     if (cmdLine.handleFlag("preferences", false)) {
  451.       openPreferences();
  452.       cmdLine.preventDefault = true;
  453.     }
  454.     if (cmdLine.handleFlag("silent", false))
  455.       cmdLine.preventDefault = true;
  456.  
  457.     var searchParam = cmdLine.handleFlagWithParam("search", false);
  458.     if (searchParam) {
  459.       doSearch(searchParam, cmdLine);
  460.       cmdLine.preventDefault = true;
  461.     }
  462.  
  463. //@line 519 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  464.     // Handle "? searchterm" for Windows Vista start menu integration
  465.     for (var i = cmdLine.length - 1; i >= 0; --i) {
  466.       var param = cmdLine.getArgument(i);
  467.       if (param.match(/^\? /)) {
  468.         cmdLine.removeArguments(i, i);
  469.         cmdLine.preventDefault = true;
  470.  
  471.         searchParam = param.substr(2);
  472.         doSearch(searchParam, cmdLine);
  473.       }
  474.     }
  475. //@line 531 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  476.   },
  477.  
  478.   helpInfo : "  -browser            Open a browser window.\n",
  479.  
  480.   /* nsIBrowserHandler */
  481.  
  482.   get defaultArgs() {
  483.     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
  484.                           .getService(nsIPrefBranch);
  485.     var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
  486.                               .getService(Components.interfaces.nsIURLFormatter);
  487.  
  488.     var overridePage = "";
  489.     var haveUpdateSession = false;
  490.     try {
  491.       switch (needHomepageOverride(prefb)) {
  492.         case OVERRIDE_NEW_PROFILE:
  493.           // New profile
  494.           overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
  495.           break;
  496.         case OVERRIDE_NEW_MSTONE:
  497.           // Existing profile, new build
  498.           copyPrefOverride();
  499.  
  500.           // Check whether we have a session to restore. If we do, we assume
  501.           // that this is an "update" session.
  502.           var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
  503.                              .getService(Components.interfaces.nsISessionStartup);
  504.           haveUpdateSession = ss.doRestore();
  505.           overridePage = formatter.formatURLPref("startup.homepage_override_url");
  506.           break;
  507.     }
  508.     } catch (ex) {}
  509.  
  510.     // formatURLPref might return "about:blank" if getting the pref fails
  511.     if (overridePage == "about:blank")
  512.       overridePage = "";
  513.  
  514.     var startPage = "";
  515.     try {
  516.       var choice = prefb.getIntPref("browser.startup.page");
  517.       if (choice == 1 || choice == 3)
  518.         startPage = this.startPage;
  519.  
  520.       if (choice == 2)
  521.         startPage = Components.classes["@mozilla.org/browser/global-history;2"]
  522.                               .getService(nsIBrowserHistory).lastPageVisited;
  523.     } catch (e) {
  524.       Components.utils.reportError(e);
  525.     }
  526.  
  527.     if (startPage == "about:blank")
  528.       startPage = "";
  529.  
  530.     // Only show the startPage if we're not restoring an update session.
  531.     if (overridePage && startPage && !haveUpdateSession)
  532.       return overridePage + "|" + startPage;
  533.  
  534.     return overridePage || startPage || "about:blank";
  535.   },
  536.  
  537.   get startPage() {
  538.     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
  539.                           .getService(nsIPrefBranch);
  540.  
  541.     var uri = prefb.getComplexValue("browser.startup.homepage",
  542.                                     nsIPrefLocalizedString).data;
  543.  
  544.     if (!uri) {
  545.       prefb.clearUserPref("browser.startup.homepage");
  546.       uri = prefb.getComplexValue("browser.startup.homepage",
  547.                                   nsIPrefLocalizedString).data;
  548.     }
  549.                                 
  550.     var count;
  551.     try {
  552.       count = prefb.getIntPref("browser.startup.homepage.count");
  553.     }
  554.     catch (e) {
  555.       return uri;
  556.     }
  557.  
  558.     for (var i = 1; i < count; ++i) {
  559.       try {
  560.         var page = prefb.getComplexValue("browser.startup.homepage." + i,
  561.                                          nsIPrefLocalizedString).data;
  562.         uri += "\n" + page;
  563.       }
  564.       catch (e) {
  565.       }
  566.     }
  567.  
  568.     return uri;
  569.   },
  570.  
  571.   mFeatures : null,
  572.  
  573.   getFeatures : function bch_features(cmdLine) {
  574.     if (this.mFeatures === null) {
  575.       this.mFeatures = "";
  576.  
  577.       try {
  578.         var width = cmdLine.handleFlagWithParam("width", false);
  579.         var height = cmdLine.handleFlagWithParam("height", false);
  580.  
  581.         if (width)
  582.           this.mFeatures += ",width=" + width;
  583.         if (height)
  584.           this.mFeatures += ",height=" + height;
  585.       }
  586.       catch (e) {
  587.       }
  588.     }
  589.  
  590.     return this.mFeatures;
  591.   },
  592.  
  593.   /* nsIContentHandler */
  594.  
  595.   handleContent : function bch_handleContent(contentType, context, request) {
  596.     try {
  597.       var webNavInfo = Components.classes["@mozilla.org/webnavigation-info;1"]
  598.                                  .getService(nsIWebNavigationInfo);
  599.       if (!webNavInfo.isTypeSupported(contentType, null)) {
  600.         throw NS_ERROR_WONT_HANDLE_CONTENT;
  601.       }
  602.     } catch (e) {
  603.       throw NS_ERROR_WONT_HANDLE_CONTENT;
  604.     }
  605.  
  606.     request.QueryInterface(nsIChannel);
  607.     handURIToExistingBrowser(request.URI,
  608.       nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null);
  609.     request.cancel(NS_BINDING_ABORTED);
  610.   },
  611.  
  612.   /* nsICommandLineValidator */
  613.   validate : function bch_validate(cmdLine) {
  614.     // Other handlers may use osint so only handle the osint flag if the url
  615.     // flag is also present and the command line is valid.
  616.     var osintFlagIdx = cmdLine.findFlag("osint", false);
  617.     var urlFlagIdx = cmdLine.findFlag("url", false);
  618.     if (urlFlagIdx > -1 && (osintFlagIdx > -1 ||
  619.         cmdLine.state == nsICommandLine.STATE_REMOTE_EXPLICIT)) {
  620.       var urlParam = cmdLine.getArgument(urlFlagIdx + 1);
  621.       if (cmdLine.length != urlFlagIdx + 2 || /firefoxurl:/.test(urlParam))
  622.         throw NS_ERROR_ABORT;
  623.       cmdLine.handleFlag("osint", false)
  624.     }
  625.   },
  626.  
  627.   /* nsIFactory */
  628.   createInstance: function bch_CI(outer, iid) {
  629.     if (outer != null)
  630.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  631.  
  632.     return this.QueryInterface(iid);
  633.   },
  634.     
  635.   lockFactory : function bch_lock(lock) {
  636.     /* no-op */
  637.   }
  638. };
  639.  
  640. const bch_contractID = "@mozilla.org/browser/clh;1";
  641. const bch_CID = Components.ID("{5d0ce354-df01-421a-83fb-7ead0990c24e}");
  642. const CONTRACTID_PREFIX = "@mozilla.org/uriloader/content-handler;1?type=";
  643.  
  644. function handURIToExistingBrowser(uri, location, cmdLine)
  645. {
  646.   if (!shouldLoadURI(uri))
  647.     return;
  648.  
  649.   var navWin = getMostRecentBrowserWindow();
  650.   if (!navWin) {
  651.     // if we couldn't load it in an existing window, open a new one
  652.     openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
  653.                "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
  654.                uri.spec);
  655.     return;
  656.   }
  657.  
  658.   var navNav = navWin.QueryInterface(nsIInterfaceRequestor)
  659.                      .getInterface(nsIWebNavigation);
  660.   var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem;
  661.   var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor)
  662.                         .getInterface(nsIDOMWindow);
  663.   var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow;
  664.   bwin.openURI(uri, null, location,
  665.                nsIBrowserDOMWindow.OPEN_EXTERNAL);
  666. }
  667.  
  668.  
  669. var nsDefaultCommandLineHandler = {
  670.   /* nsISupports */
  671.   QueryInterface : function dch_QI(iid) {
  672.     if (!iid.equals(nsISupports) &&
  673.         !iid.equals(nsICommandLineHandler) &&
  674.         !iid.equals(nsIFactory))
  675.       throw Components.results.NS_ERROR_NO_INTERFACE;
  676.  
  677.     return this;
  678.   },
  679.  
  680.   // List of uri's that were passed via the command line without the app
  681.   // running and have already been handled. This is compared against uri's
  682.   // opened using DDE on Win32 so we only open one of the requests.
  683.   _handledURIs: [ ],
  684. //@line 740 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  685.   _haveProfile: false,
  686. //@line 742 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  687.  
  688.   /* nsICommandLineHandler */
  689.   handle : function dch_handle(cmdLine) {
  690.     var urilist = [];
  691.  
  692. //@line 748 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  693.     // If we don't have a profile selected yet (e.g. the Profile Manager is
  694.     // displayed) we will crash if we open an url and then select a profile. To
  695.     // prevent this handle all url command line flags and set the command line's
  696.     // preventDefault to true to prevent the display of the ui. The initial
  697.     // command line will be retained when nsAppRunner calls LaunchChild though
  698.     // urls launched after the initial launch will be lost.
  699.     if (!this._haveProfile) {
  700.       try {
  701.         // This will throw when a profile has not been selected.
  702.         var fl = Components.classes["@mozilla.org/file/directory_service;1"]
  703.                            .getService(Components.interfaces.nsIProperties);
  704.         var dir = fl.get("ProfD", Components.interfaces.nsILocalFile);
  705.         this._haveProfile = true;
  706.       }
  707.       catch (e) {
  708.         while ((ar = cmdLine.handleFlagWithParam("url", false))) { }
  709.         cmdLine.preventDefault = true;
  710.       }
  711.     }
  712. //@line 768 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  713.  
  714.     try {
  715.       var ar;
  716.       while ((ar = cmdLine.handleFlagWithParam("url", false))) {
  717.         var found = false;
  718.         var uri = resolveURIInternal(cmdLine, ar);
  719.         // count will never be greater than zero except on Win32.
  720.         var count = this._handledURIs.length;
  721.         for (var i = 0; i < count; ++i) {
  722.           if (this._handledURIs[i].spec == uri.spec) {
  723.             this._handledURIs.splice(i, 1);
  724.             found = true;
  725.             cmdLine.preventDefault = true;
  726.             break;
  727.           }
  728.         }
  729.         if (!found) {
  730.           urilist.push(uri);
  731.           // The requestpending command line flag is only used on Win32.
  732.           if (cmdLine.handleFlag("requestpending", false) &&
  733.               cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH)
  734.             this._handledURIs.push(uri)
  735.         }
  736.       }
  737.     }
  738.     catch (e) {
  739.       Components.utils.reportError(e);
  740.     }
  741.  
  742.     count = cmdLine.length;
  743.  
  744.     for (i = 0; i < count; ++i) {
  745.       var curarg = cmdLine.getArgument(i);
  746.       if (curarg.match(/^-/)) {
  747.         Components.utils.reportError("Warning: unrecognized command line flag " + curarg + "\n");
  748.         // To emulate the pre-nsICommandLine behavior, we ignore
  749.         // the argument after an unrecognized flag.
  750.         ++i;
  751.       } else {
  752.         try {
  753.           urilist.push(resolveURIInternal(cmdLine, curarg));
  754.         }
  755.         catch (e) {
  756.           Components.utils.reportError("Error opening URI '" + curarg + "' from the command line: " + e + "\n");
  757.         }
  758.       }
  759.     }
  760.  
  761.     if (urilist.length) {
  762.       if (cmdLine.state != nsICommandLine.STATE_INITIAL_LAUNCH &&
  763.           urilist.length == 1) {
  764.         // Try to find an existing window and load our URI into the
  765.         // current tab, new tab, or new window as prefs determine.
  766.         try {
  767.           handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine);
  768.           return;
  769.         }
  770.         catch (e) {
  771.         }
  772.       }
  773.  
  774.       var URLlist = urilist.filter(shouldLoadURI).map(function (u) u.spec);
  775.       if (URLlist.length) {
  776.         openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
  777.                    "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
  778.                    URLlist);
  779.       }
  780.  
  781.     }
  782.     else if (!cmdLine.preventDefault) {
  783.       // Passing defaultArgs, so use NO_EXTERNAL_URIS
  784.       openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
  785.                  "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
  786.                  nsBrowserContentHandler.defaultArgs, NO_EXTERNAL_URIS);
  787.     }
  788.   },
  789.  
  790.   // XXX localize me... how?
  791.   helpInfo : "Usage: firefox [-flags] [<url>]\n",
  792.  
  793.   /* nsIFactory */
  794.   createInstance: function dch_CI(outer, iid) {
  795.     if (outer != null)
  796.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  797.  
  798.     return this.QueryInterface(iid);
  799.   },
  800.     
  801.   lockFactory : function dch_lock(lock) {
  802.     /* no-op */
  803.   }
  804. };
  805.  
  806. const dch_contractID = "@mozilla.org/browser/final-clh;1";
  807. const dch_CID = Components.ID("{47cd0651-b1be-4a0f-b5c4-10e5a573ef71}");
  808.  
  809. var Module = {
  810.   /* nsISupports */
  811.   QueryInterface: function mod_QI(iid) {
  812.     if (iid.equals(Components.interfaces.nsIModule) ||
  813.         iid.equals(Components.interfaces.nsISupports))
  814.       return this;
  815.  
  816.     throw Components.results.NS_ERROR_NO_INTERFACE;
  817.   },
  818.  
  819.   /* nsIModule */
  820.   getClassObject: function mod_getco(compMgr, cid, iid) {
  821.     if (cid.equals(bch_CID))
  822.       return nsBrowserContentHandler.QueryInterface(iid);
  823.  
  824.     if (cid.equals(dch_CID))
  825.       return nsDefaultCommandLineHandler.QueryInterface(iid);
  826.  
  827.     throw Components.results.NS_ERROR_NO_INTERFACE;
  828.   },
  829.     
  830.   registerSelf: function mod_regself(compMgr, fileSpec, location, type) {
  831.     if (Components.classes["@mozilla.org/xre/app-info;1"]) {
  832.       // Don't register these if Firefox is launching a XULRunner application
  833.       const FIREFOX_UID = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
  834.       var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
  835.                               .getService(Components.interfaces.nsIXULAppInfo);
  836.       if (appInfo.ID != FIREFOX_UID)
  837.         return;
  838.     }
  839.  
  840.     var compReg =
  841.       compMgr.QueryInterface( Components.interfaces.nsIComponentRegistrar );
  842.  
  843.     compReg.registerFactoryLocation( bch_CID,
  844.                                      "nsBrowserContentHandler",
  845.                                      bch_contractID,
  846.                                      fileSpec,
  847.                                      location,
  848.                                      type );
  849.     compReg.registerFactoryLocation( dch_CID,
  850.                                      "nsDefaultCommandLineHandler",
  851.                                      dch_contractID,
  852.                                      fileSpec,
  853.                                      location,
  854.                                      type );
  855.  
  856.     function registerType(contentType) {
  857.       compReg.registerFactoryLocation( bch_CID,
  858.                                        "Browser Cmdline Handler",
  859.                                        CONTRACTID_PREFIX + contentType,
  860.                                        fileSpec,
  861.                                        location,
  862.                                        type );
  863.     }
  864.  
  865.     registerType("text/html");
  866.     registerType("application/vnd.mozilla.xul+xml");
  867. //@line 923 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  868.     registerType("image/svg+xml");
  869. //@line 925 "e:\fx19rel\WINNT_5.2_Depend\mozilla\browser\components\nsBrowserContentHandler.js"
  870.     registerType("text/rdf");
  871.     registerType("text/xml");
  872.     registerType("application/xhtml+xml");
  873.     registerType("text/css");
  874.     registerType("text/plain");
  875.     registerType("image/gif");
  876.     registerType("image/jpeg");
  877.     registerType("image/jpg");
  878.     registerType("image/png");
  879.     registerType("image/bmp");
  880.     registerType("image/x-icon");
  881.     registerType("image/vnd.microsoft.icon");
  882.     registerType("image/x-xbitmap");
  883.     registerType("application/http-index-format");
  884.  
  885.     var catMan = Components.classes["@mozilla.org/categorymanager;1"]
  886.                            .getService(nsICategoryManager);
  887.  
  888.     catMan.addCategoryEntry("command-line-handler",
  889.                             "m-browser",
  890.                             bch_contractID, true, true);
  891.     catMan.addCategoryEntry("command-line-handler",
  892.                             "x-default",
  893.                             dch_contractID, true, true);
  894.     catMan.addCategoryEntry("command-line-validator",
  895.                             "b-browser",
  896.                             bch_contractID, true, true);
  897.   },
  898.     
  899.   unregisterSelf : function mod_unregself(compMgr, location, type) {
  900.     var compReg = compMgr.QueryInterface(nsIComponentRegistrar);
  901.     compReg.unregisterFactoryLocation(bch_CID, location);
  902.     compReg.unregisterFactoryLocation(dch_CID, location);
  903.  
  904.     var catMan = Components.classes["@mozilla.org/categorymanager;1"]
  905.                            .getService(nsICategoryManager);
  906.  
  907.     catMan.deleteCategoryEntry("command-line-handler",
  908.                                "m-browser", true);
  909.     catMan.deleteCategoryEntry("command-line-handler",
  910.                                "x-default", true);
  911.     catMan.deleteCategoryEntry("command-line-validator",
  912.                                "b-browser", true);
  913.   },
  914.  
  915.   canUnload: function(compMgr) {
  916.     return true;
  917.   }
  918. };
  919.  
  920. // NSGetModule: Return the nsIModule object.
  921. function NSGetModule(compMgr, fileSpec) {
  922.   return Module;
  923. }
  924.